local Timer = require("core.Timer")
local Msg = require("core.Msg")
local Human = require("core.Human")
local FriendDefine = require("friend.FriendDefine")
local RoleDBLogic = require("role.RoleDBLogic")
local FriendDBLogic = require("friend.FriendDBLogic")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local FriendExcel = require("excel.Friend")
local RoleFFI = require("role.RoleFFI")
local ShenbingExcel = require("excel.Shenbing").shenbing
local table = _G.table
local GmCommon = require("chat.GmCommon")
local VipLevel = require("vip.VipLevel")
local Log = require("common.Log")
local Dict2 = require("core.Dict2")
local ChatReport = require("chat.ChatReport")
local PfLogic = require("tencentApi.PfLogic")

friend_request_online = friend_request_online or {}
friend_request_offline = friend_request_offline or {}

local fields = {
	name = 1,
	head = 1,
	lv = 1,
	sex = 1,
	familyUuid = 1,
	sign = 1,
	zhandouli = 1,
	putonShenbing = 1,
	historyYuanbao = 1,
}

--function offLineFriendRequset(human)
--	local offlineRequest = friend_request_offline[human._id]
--	if not offlineRequest then
--		return
--	end 
--	
--	friend_request_offline[human._id] = {}
--	
--	for k,v in pairs(offlineRequest) do 
--		GC_FRIEND_ADD_NOTIFY(k,human._id,true)
--	end	
--end

function clearFriendRequset(human)
  local onlineRequest = friend_request_online[human._id]
  if not onlineRequest then
    return
  end 
  for k in pairs(onlineRequest) do
    onlineRequest[k] = nil
  end
end
--检查是否重复申请
function hasFriendRequest(invitorUuid,targetUuid)
	if not friend_request_online[targetUuid] then
		friend_request_online[targetUuid] = {}
		return false
	end
	
	local time = friend_request_online[targetUuid][invitorUuid]
	if not time then
		return false
	end
	
	local now = os.time()
	if now - time > 300 then	--	5min
		friend_request_online[targetUuid][invitorUuid] = nil
		return false
	end
	return true
end
--检查离线请求
--function hasFriendRequestOffline(invitorUuid,targetUuid)
--	if not friend_request_offline[targetUuid] then
--		friend_request_offline[targetUuid] = {}
--		return false
--	end
--	
--	local time = friend_request_offline[targetUuid][invitorUuid]
--	if not time then
--		return false
--	end
--	
--	local now = os.time()
--	if now - time > 300 then	--	5min
--		friend_request_offline[targetUuid][invitorUuid] = nil
--		return false
--	end
--	return true
--end

function onAddFriendRequest(invitorUuid,targetUuid,online)
	
	if online then
		local requestData = friend_request_online[targetUuid]
		requestData[invitorUuid] = os.time()
	else
--		if not friend_request_offline[targetUuid] then
--			friend_request_offline[targetUuid] = {}
--		end
--		local requestData = friend_request_offline[targetUuid]
--		requestData[invitorUuid] = os.time()
	end
	
end

function onAddFriendRequestRet(invitorUuid,targetUuid)
	if not friend_request_online[targetUuid] then
		return
	end
	local requestData = friend_request_online[targetUuid]
	requestData[invitorUuid] = nil
end

function makeFriend(friend,db,id,type,data, isOnline)	
	friend.name = RoleFFI.ffi_string(db.name)
	friend.id = id or -1
	friend.type = type or 0
	friend.uuid = RoleFFI.ffi_string(db._id)
	friend.head = db.head
	friend.lv = db.lv
	friend.sex = db.sex
	friend.vipLv = VipLevel.getVipLv(db)
	if db.putonShenbing ~= 0 then	
    friend.sign = ShenbingExcel[db.putonShenbing].sbMingzi
  else
    friend.sign = ""
  end
	
	friend.createTime = 0
	friend.qinmi = 0
	friend.isOnline = isOnline or 0
	local human = {}
	human.db = db
	if PfLogic.isYellowShow(human) then
    friend.yellowVipLv = db.yellowVipLv or 0
    friend.yellowYearVip = db.yellowYearVip or 0
  else
    friend.yellowVipLv = 0
    friend.yellowYearVip = 0
  end
  if PfLogic.isBlueShow(human) then
    friend.blueVipLv = db.blueVipLv or 0
    friend.blueYearVip = db.blueYearVip or 0
    friend.blueSuperVip = db.blueSuperVip or 0
    if PfLogic.is3366Show(human) then
        friend.level3366 = db.level3366 or 0
    else
        friend.level3366 = 0
    end
  else
    friend.blueVipLv = 0
    friend.blueYearVip = 0
    friend.blueSuperVip = 0 
    friend.level3366 = 0   
  end
  friend.arg = 0
	if not isOnline then
  	for k in pairs(Human.onlineUuid) do
      if k == friend.uuid then
        friend.isOnline = 1
      end
  	end
	end

	if data then
		friend.createTime = data.create_time or 0
		friend.qinmi = 0
	end
		
	friend.zhandouli = db.zhandouli	
	friend.args[0] = 0	
end

function makeComment(msgComment,comment)
	local ownerDB = RoleDBLogic.getDb(comment.ownerUuid, fields)
	if not ownerDB then
		assert()
	end
	makeFriend(msgComment.owner,ownerDB)
	msgComment.content = comment.content
	msgComment.time = comment.time
end

function GC_FRIEND_FIND(human,db)
	local msgRet = Msg.gc.GC_FRIEND_FIND
	makeFriend(msgRet.friend,db,-1)
	Msg.send(msgRet,human.fd)
end

function sendOnLineNotify(human,fd,data,type)
	local msgRet = Msg.gc.GC_FRIEND_UPDATE
	makeFriend(msgRet.friend,human.db,human.id,type,data, 1)
	Msg.send(msgRet,fd)
end

function sendOffLineNotify(human,fd,data)
	local msgRet = Msg.gc.GC_FRIEND_UPDATE
	makeFriend(msgRet.friend,human.db,-1,FriendDefine.FRIEND,data, 0)
	Msg.send(msgRet,fd)
end

function GC_FRIEND_UPDATE(human)
	local msgRet = Msg.gc.GC_FRIEND_UPDATE
	local onlineUuid = Human.onlineUuid
	local target = nil
	if not human.friend then
    return
	end
  for k, v in pairs(human.friend) do 
		target = onlineUuid[k]
		if target then
			makeFriend(msgRet.friend,human.db,human.id,FriendDefine.FRIEND,v)
			Msg.send(msgRet,target.fd)
		end
	end
end

function sendIsAutoAdd(human)
  local msgRet = Msg.gc.GC_FRIEND_AUTO_ADD
  msgRet.isAuto = human.db.isAutoAddFriend
  Msg.send(msgRet, human.fd)
end

function changeAutoAdd(human)
  human.db.isAutoAddFriend = (human.db.isAutoAddFriend + 1) % 2
  sendIsAutoAdd(human)
end

function sendFriendList(human)

	local msgRet = Msg.gc.GC_FRIEND_LIST
	msgRet.friends[0] = 0
	
	local len = 0	
	local onlineUuid = Human.onlineUuid
	
	-- friend
	for k,v in pairs(human.friend) do
		local friend = onlineUuid[k]
		len = len + 1
		makeFriend(msgRet.friends[len],RoleDBLogic.getDb(k, fields),friend and friend.id,FriendDefine.FRIEND,v)
	end
	if len > 0 then
		msgRet.friends[0] = len
		Msg.send(msgRet,human.fd)
	end
	
end

function sendBlackList(human)
	if not human then
    return
	end
	local msgRet = Msg.gc.GC_BLACK_LIST
	msgRet.blacks[0] = 0
	
	local len = 0	
	local onlineUuid = Human.onlineUuid
	
	-- black
	for i=0, human.db.blackLen - 1 do
	  local friend = onlineUuid[RoleFFI.ffi_string(human.db.black[i].uuid)]
	  local id = -1
    local pass = true
    local db = nil
    
    if friend then
      id = friend.id
      db = friend.db
    else  
      pass , db = RoleDBLogic.isUuidExistInDB(RoleFFI.ffi_string(human.db.black[i].uuid)) 
    end
    
    if pass then
      len = len + 1
      makeFriend(msgRet.blacks[len],db,id,FriendDefine.BLACK, human.db.black[i])
    end
	end
	if len > 0 then
	  msgRet.blacks[0] = len
    Msg.send(msgRet,human.fd)
  end
end

function sendEnemyList(human)	
	local msgRet = Msg.gc.GC_ENEMY_LIST
	msgRet.enemys[0] = 0
	local len = 0
	local onlineUuid = Human.onlineUuid
	for i=0, human.db.enemyLen - 1 do 
		local enemy = onlineUuid[RoleFFI.ffi_string(human.db.enemy[i].uuid)]
		local pass = true
		local db = nil
		if enemy then
			db = enemy.db
		else
  		pass , db = RoleDBLogic.isUuidExistInDB(RoleFFI.ffi_string(human.db.enemy[i].uuid))
		end
		if pass then
			len = len + 1
			makeFriend(msgRet.enemys[len],db,nil,FriendDefine.ENEMY)
			msgRet.enemys[len].args[0] = 2
			msgRet.enemys[len].args[1] = human.db.enemy[i].killedTimes 
			msgRet.enemys[len].args[2] =  human.db.enemy[i].revengeTimes			
		end
	end
	msgRet.enemys[0] = len
	Msg.send(msgRet,human.fd)	
end

function GC_FRIEND_ADD_NOTIFY(invitorUuid,targetUuid,noTip)

	local pass1,invitorDB = RoleDBLogic.isUuidExistInDB(invitorUuid)
	local pass2,targetDB = RoleDBLogic.isUuidExistInDB(targetUuid)
	local onlineUuid = Human.onlineUuid
	
	if not pass1 or not pass2 then
		return 
	end
	
	 
  local msgErr = Msg.gc.GC_BROADCAST
  msgErr.type = Lang.DOWN

	local invitor = onlineUuid[invitorUuid]
	local invitorID = -1
	local target = onlineUuid[targetUuid]
	local targetOnline = false
	
	if invitor then
		invitorDB = invitor.db
		invitorID = invitor.id
	end
	
	if target then
		targetDB = target.db
		targetOnline = true
  else    
    msgErr.msg = Lang.FRIEND_NOT_ONLINE
    return Msg.send(msgErr,invitor.fd)
	end
	
	if invitorUuid == targetUuid then
		if invitor then
			msgErr.msg = Lang.FRIEND_CAN_NOT_ADD_FRIEND_SELF
			Msg.send(msgErr,invitor.fd)
		end	
		return
	end
	
	-- check friend
	if isFriend(invitorUuid,targetUuid) then
		if invitor then
			msgErr.msg = Lang.FRIEND_HAS_BEEN_FRIEND
			Msg.send(msgErr,invitor.fd)
		end		
		return
	end
	
	-- check double request
	if hasFriendRequest(invitorUuid,targetUuid) then
		if invitor then
			msgErr.msg = Lang.FRIEND_DOUBLE_INVITE
			Msg.send(msgErr,invitor.fd)
		end
		return
	end
	
--	if hasFriendRequestOffline(invitorUuid,targetUuid) then
		if not targetOnline then
			msgErr.msg = Lang.FRIEND_NOT_ONLINE --Lang.FRIEND_DOUBLE_INVITE
			Msg.send(msgErr,invitor.fd)
			return
		end		

--	end
	
	if isBlack(targetDB,invitorUuid) then
		if invitor then
			msgErr.msg = Lang.FRIEND_U_IN_TARGET_BLACK
			Msg.send(msgErr,invitor.fd)
		end
		return
	end
			
	if invitor and not noTip and target and target.db.isAutoAddFriend == 0 then
		msgErr.msg = Lang.FRIEND_SEND_ADD_FRIEND_QUERY_OK
		Msg.send(msgErr,invitor.fd)
--		addRecent(invitor,targetUuid)
	end
				
	if target and target.db.isAutoAddFriend == 0 then
		local msgRet = Msg.gc.GC_FRIEND_ADD_NOTIFY
		local friendAddNet = msgRet.friendAddNet
		friendAddNet.invitorName = RoleFFI.ffi_string(invitorDB.name)
		friendAddNet.invitorUuid = RoleFFI.ffi_string(invitorDB._id)
		friendAddNet.invitorID = invitorID
		friendAddNet.invitorSex = invitorDB.sex
		friendAddNet.invitorLv = invitorDB.lv
		friendAddNet.invitorHead = invitorDB.head
		friendAddNet.vipLv = VipLevel.getVipLv(invitorDB)
		friendAddNet.zhandouli = invitorDB.zhandouli
		local human = {}
		human.db = invitorDB
	  if PfLogic.isYellowShow(human) then
      friendAddNet.yellowVipLv = invitorDB.yellowVipLv or 0
      friendAddNet.yellowYearVip = invitorDB.yellowYearVip or 0
    else
      friendAddNet.yellowVipLv = 0
      friendAddNet.yellowYearVip = 0
    end
    if PfLogic.isBlueShow(human) then
      friendAddNet.blueVipLv = invitorDB.blueVipLv or 0
      friendAddNet.blueYearVip = invitorDB.blueYearVip or 0 
      friendAddNet.blueSuperVip = invitorDB.blueSuperVip or 0 
      if PfLogic.is3366Show(human) then
        friendAddNet.level3366 = invitorDB.level3366 or 0
      else
        friendAddNet.level3366 = 0
      end      
    else
      friendAddNet.blueVipLv = 0
      friendAddNet.blueYearVip = 0 
      friendAddNet.blueSuperVip = 0 
      friendAddNet.level3366 = 0
    end
    friendAddNet.args = 0
		Msg.send(msgRet,target.fd)
  elseif target and target.db.isAutoAddFriend == 1 then
    addFriend(invitorUuid, targetUuid)
	end
	if target.db.isAutoAddFriend ~= 1 then
	  onAddFriendRequest(invitorUuid,targetUuid,targetOnline)
	end	
end

local dict = {
	"太古遮天",
	"神创天下",
	"太古遗迹",
}

local out = {}
local out2 = {}
local tb = {}
local function name_replace(str)
	local outlen = #str
	for i = 1, outlen do
		out[i] = string.sub(str, i, i)
	end
	local ac
	for _, v in ipairs(dict) do
		for cnt = 1, 64 do
			if 64 <= cnt then
				assert()
			end
			local start = 1
			local tblen = 0
			for i = 1, #v do
				local vii = string.sub(v, i, i)
				for j = start, outlen do
					if out[j] == vii then
						start = j + 1
						tblen = tblen + 1
						tb[tblen] = j
						break
					end
				end
				if tblen < i then
					break
				end
			end
			if tblen < #v then
				break	
			end
			for i = tblen - 1, 1, -1 do
				for j = tb[i + 1] - 1, tb[i] + 1, -1 do
					if out[j] == out[tb[i]] then
						tb[i] = j
						break
					end
				end
			end
			if tblen * 2 < tb[tblen] - tb[1] then
				break
			end
			ac = true
			local outlen2 = 0
			for i = 1, tb[1] - 1 do
				outlen2 = outlen2 + 1
				out2[outlen2] = out[i]
			end
			outlen2 = outlen2 + 1
			out2[outlen2] = "梦幻Q仙"
			for i = tb[tblen] + 1, outlen do
				outlen2 = outlen2 + 1
				out2[outlen2] = out[i]
			end
			out, out2 = out2, out
			outlen = outlen2
		end
	end
	if ac then
		return table.concat(out, nil, 1, outlen)
	else
		return str
	end
end

function CG_FRIEND_CHAT(human,msg, onlySendToTarget)
  
	local recUuid = msg.recUuid
  if not isFriend(human._id, recUuid) then
    return Broadcast.sendBroadcast(human,Lang.MOUSE, Lang.FRIEND_CHAT_NOT_FRIEND)
  end	
	local content = GmCommon.filter(msg.content)
	
	local onlineUuid = Human.onlineUuid	
	local target = onlineUuid[recUuid]
	
	-- check lv limit
	if human.db.lv < FriendDefine.FRIEND_CHAT_LV_LIMIT then
		Broadcast.sendBroadcast(human,Lang.MOUSE,string.format(Lang.FRIEND_CHAT_SELF_LV,FriendDefine.FRIEND_CHAT_LV_LIMIT))		
		return
	end
	
	if target then
		if target.db.lv < FriendDefine.FRIEND_CHAT_LV_LIMIT then
			Broadcast.sendBroadcast(human,Lang.MOUSE,string.format(Lang.FRIEND_CHAT_TARGET_LV,FriendDefine.FRIEND_CHAT_LV_LIMIT))		
			return
		end
	else
		
		local targetDB = RoleDBLogic.getDb(recUuid, fields)
		if not targetDB then
			return
		end
		
		if targetDB.lv < FriendDefine.FRIEND_CHAT_LV_LIMIT then
			Broadcast.sendBroadcast(human,Lang.MOUSE,string.format(Lang.FRIEND_CHAT_TARGET_LV,FriendDefine.FRIEND_CHAT_LV_LIMIT))		
			return
		end 
			
	end
	
	if not target then
		return
	end
	
	if isBlack(target.db,human._id) then
		Broadcast.sendBroadcast(human,Lang.MOUSE,Lang.FRIEND_IS_BLACK_NOT_TALK)		
		return
	end
	
	if GmCommon.filter(msg.content, Dict2) ~= msg.content then
	   ChatReport.chatReport(human, msg.content)
	end
	
	local msgRet = Msg.gc.GC_FRIEND_CHAT
	msgRet.senderUuid = human._id
	msgRet.senderID = human.id
	msgRet.senderName = RoleFFI.ffi_string(human.db.name)
	msgRet.senderLv = human.db.lv
	msgRet.senderJob = 0--human.db.job
	msgRet.senderHead = human.db.head or 0
	msgRet.targetUuid = target._id
	msgRet.targetID = target.id
	msgRet.targetName = RoleFFI.ffi_string(target.db.name)
	msgRet.msg = content
	
	if human.db.gm == 100 then
		msgRet.msg = "<font color='#ffc000'>" .. msgRet.msg .. "</font>"
	end
	
  if human.db.ban_say_time and Timer.now < human.db.ban_say_time then
    Msg.send(msgRet, human.fd)
    return
  end
	if human.fd and onlySendToTarget == nil then
		Msg.send(msgRet, human.fd)
	end
	if target.fd then
		msgRet.msg = name_replace(content)
		if human.db.gm == 100 then
			msgRet.msg = "<font color='#ffc000'>" .. msgRet.msg .. "</font>"
		end
		Msg.send(msgRet, target.fd)
	end
	Log.write(Log.LOGID_OSS_FRIEND_CHAT,human._id,human.account,human.name,human.db.lv,RoleFFI.ffi_string(target.db.name), content)
end

--加好友
function addFriend(invitorUuid,targetUuid)
	
	local pass,invitorDB = RoleDBLogic.isUuidExistInDB(invitorUuid)
	if not pass then
		return 
	end
	
	local pass,targetDB = RoleDBLogic.isUuidExistInDB(targetUuid) 
	if not pass then
		return 
	end
	
	local onlineUuid = Human.onlineUuid
	local invitor = onlineUuid[invitorUuid]
	local target = onlineUuid[targetUuid]
	
	local msgErr = Msg.gc.GC_BROADCAST
	msgErr.type = Lang.DOWN
	
	if invitorUuid == targetUuid then
		if target then
			msgErr.msg = Lang.FRIEND_CAN_NOT_ADD_FRIEND_SELF
			Msg.send(msgErr,target.fd)
		end
		return
	end

	if isFriend(invitorUuid,targetUuid) then
		if target then
			msgErr.msg = Lang.FRIEND_HAS_BEEN_FRIEND
			Msg.send(msgErr,target.fd)
		end
		return 
	end
	
	if isFriendListFull(invitorUuid) then
		if target then
			msgErr.msg = Lang.FRIEND_TARGET_FRIEND_LIST_FULL
			Msg.send(msgErr,target.fd)
		end
		return
	end
	
	if isFriendListFull(targetUuid) then
		if target then
			msgErr.msg = Lang.FRIEND_SELF_FRIEND_LIST_FULL
			Msg.send(msgErr,target.fd)
		end
		
		if invitor then
			msgErr.msg = Lang.FRIEND_TARGET_FRIEND_LIST_FULL
			Msg.send(msgErr,invitor.fd)
		end
		return
	end
	
	local invitorID = -1
	local targetID = -1
	
	if invitor then
		invitorDB = invitor.db
		invitorID = invitor.id
	end
	
	if target then
		targetDB = target.db
		targetID = target.id
	end
	if isBlack(targetDB, invitorUuid) then	
		if target then
			msgErr.msg = Lang.FRIEND_TARGET_IN_SELF_BLACK
			Msg.send(msgErr,target.fd)
		end
		return
	end
	
	local now = os.time()
	-- set db data
	local dbPass,dbData = FriendDBLogic.addFriendData(RoleFFI.ffi_string(invitorDB._id),RoleFFI.ffi_string(targetDB._id),now)
	if not dbPass then
		return
	end
	
	-- del black
	delBlack(invitorUuid,targetUuid)
	sendBlackList(invitor)
	-- add friend
	if invitor then
		invitor.friend[targetUuid] = dbData
	end
	
	if target then
		target.friend[invitorUuid] = dbData
	end
  msgErr.msg = Lang.FRIEND_ADD_FRIEND_OK
  if invitor then
    Msg.send(msgErr,invitor.fd)
  end
  
	-- send msg
	local msgRet = Msg.gc.GC_FRIEND_ADD
	if invitorID ~= -1 and invitor then
		makeFriend(msgRet.friend,targetDB,targetID,FriendDefine.FRIEND,dbData)
		Msg.send(msgRet,invitor.fd)
	end
	
	if targetID ~= -1 and target then
		makeFriend(msgRet.friend,invitorDB,invitorID,FriendDefine.FRIEND,dbData)
		Msg.send(msgRet,target.fd)
	end
end

-- 加黑名单
function addBlack(human,targetUuid)
	
	local msgErr = Msg.gc.GC_BROADCAST
	msgErr.type = Lang.DOWN

	if human._id == targetUuid then
		msgErr.msg = Lang.FRIEND_CAN_NOT_ADD_BLACK_SELF
		Msg.send(msgErr,human.fd)
		return
	end
	
	if isBlack(human.db,targetUuid) then
		msgErr.msg = Lang.FRIEND_HAS_BEEN_BLACK
		Msg.send(msgErr,human.fd)
		return
	end
	
	if isBlackListFull(human) then
		msgErr.msg = Lang.FRIEND_SELF_BLACK_LIST_FULL
		Msg.send(msgErr,human.fd)
		return
	end
	local pass,targetDB = RoleDBLogic.isUuidExistInDB(targetUuid) 
	if not pass then
		msgErr.msg = Lang.FRIEND_TARGET_UUID_INVALID
		Msg.send(msgErr,human.fd)
		return 
	end
	
	local targetID = -1
	local onlineUuid = Human.onlineUuid
	local target = onlineUuid[targetUuid]
	if target then
		targetID = target.id
		targetDB = target.db
	end
	
	delFriend(human._id,targetUuid,true)
	
	human.db.black[human.db.blackLen].uuid = targetUuid
	human.db.black[human.db.blackLen].create_time = os.time()
	human.db.blackLen = human.db.blackLen + 1
	local msgRet = Msg.gc.GC_FRIEND_ADD
	makeFriend(msgRet.friend,targetDB,targetID,FriendDefine.BLACK,human.db.black[human.db.blackLen - 1])
	Msg.send(msgRet,human.fd)
	
end


local function hasEnemy(human,uuid)
  for i=0, human.db.enemyLen - 1 do
    if RoleFFI.ffi_string(human.db.enemy[i].uuid) == uuid then
      return i
    end
  end
  return nil
end

function addEnemy(human,killUuid)
	local killer = Human.onlineUuid[killUuid]
	if not killer then
    return
  end
	local index = hasEnemy(human,killer._id)
	if index then
    human.db.enemy[index].killedTimes = human.db.enemy[index].killedTimes + 1 
    sendEnemyList(human)
	else	
  	if human.db.enemyLen >= FriendDefine.ENEMY_COUNT then
      return
    end
    human.db.enemy[human.db.enemyLen] = {}
  	human.db.enemy[human.db.enemyLen].uuid = killUuid
  	human.db.enemy[human.db.enemyLen].revengeTimes = 0
  	human.db.enemy[human.db.enemyLen].killedTimes = 1
  	human.db.enemyLen = human.db.enemyLen + 1
  	local msgRet = Msg.gc.GC_FRIEND_ADD
    makeFriend(msgRet.friend,killer.db,killer.id,FriendDefine.ENEMY)
    msgRet.friend.args[0] = 2
    msgRet.friend.args[1] = human.db.enemy[human.db.enemyLen].killedTimes
    msgRet.friend.args[2] = human.db.enemy[human.db.enemyLen].revengeTimes
    Msg.send(msgRet,human.fd)
  end
  index = hasEnemy(killer,human._id)
  if index then
    killer.db.enemy[index].revengeTimes = killer.db.enemy[index].revengeTimes + 1 
    sendEnemyList(human)
  end
end

-- 删好友
function delFriend(srcUuid,targetUuid,tip)
	
	local pass,srcDB = RoleDBLogic.isUuidExistInDB(srcUuid)	
	if not pass then
		return
	end
		
	local pass,targetDB = RoleDBLogic.isUuidExistInDB(targetUuid)
	if not pass then
		return 
	end
	
	local onlineUuid = Human.onlineUuid
	local src = onlineUuid[srcUuid]
	local target = onlineUuid[targetUuid]
	
	local msgErr = Msg.gc.GC_BROADCAST
	msgErr.type = Lang.DOWN
	
	if not isFriend(srcUuid,targetUuid) then
		if src and not tip then
			msgErr.msg = Lang.FRIEND_NOT_FRIEND
			Msg.send(msgErr,src.fd)
		end
		return
	end	
	
	local fds = {}
	local len = 0
	if src then
		srcDB = src.db
		if src.fd then
			len = len + 1
			fds[0] = len
			fds[len] = src.fd
		end
		src.friend[targetUuid] = nil
	end
	
	if target then
		targetDB = target.db
		if target.fd then
			len = len + 1
			fds[0] = len
			fds[len] = target.fd
		end
		target.friend[srcUuid] = nil
	end
	
	-- set db data
	FriendDBLogic.delFriendData(srcUuid,targetUuid)
	
	-- send msg
	local msgRet = Msg.gc.GC_FRIEND_DEL
	msgRet.type = FriendDefine.DEL_FRIEND
	msgRet.srcUuid = srcUuid
	msgRet.targetUuid = targetUuid
	Msg.sendMulti(msgRet, fds)
	
--	Log.write(Log.LOGID_OSS_FRIEND,srcDB._id,srcDB.account,srcDB.name,srcDB.lv,targetDB.name,LogDefine.FRIEND.DEL)
--	Log.write(Log.LOGID_OSS_FRIEND,targetDB._id,targetDB.account,targetDB.name,targetDB.lv,srcDB.name,LogDefine.FRIEND.DEL)
	
end

function delBlack(srcUuid,targetUuid)

	local pass,srcDB = RoleDBLogic.isUuidExistInDB(srcUuid)
	if not pass then
		return
	end
	
	local pass = RoleDBLogic.isUuidExistInDB(targetUuid)
	if not pass then
		return 
	end
	
	local onlineUuid = Human.onlineUuid
	local src = onlineUuid[srcUuid]
	local target = onlineUuid[targetUuid]
	
	local fd = nil
	if src then
		srcDB = src.db
		fd = src.fd
	end
	
	if target then
		target = target.db
	end
	
	local msgErr = Msg.gc.GC_BROADCAST
	msgErr.type = Lang.DOWN
	
	if not isBlack(srcDB,targetUuid) then
		return
	end
	
	-- del black
	local num = 0
	for i=0,srcDB.blackLen -1 do
    if RoleFFI.ffi_string(srcDB.black[i].uuid) == targetUuid then
      num = i
    end
	end
	srcDB.blackLen = srcDB.blackLen - 1	
	for i=0,srcDB.blackLen - 1 do
    if num < i then
      srcDB.black[i].uuid = srcDB.black[i + 1].uuid
      srcDB.black[i].create_time = srcDB.black[i + 1].create_time 
    end
  end
	if fd ~= nil then
		local msgRet = Msg.gc.GC_FRIEND_DEL
		msgRet.type = FriendDefine.DEL_BLACK
		msgRet.srcUuid = srcUuid
		msgRet.targetUuid = targetUuid
		Msg.send(msgRet, fd)
	end
	
end

function delEnemy(human,targetUuid)
	
	local pass = RoleDBLogic.isUuidExistInDB(targetUuid)
	if not pass then
		return
	end
	
	local delIndex = nil
	for i=0, human.db.enemyLen - 1 do
    if RoleFFI.ffi_string(human.db.enemy[i].uuid) == targetUuid then
      delIndex = i
      break
    end
	end

	if not delIndex then
		Broadcast.sendBroadcast(human,Lang.DOWN,Lang.FRIEND_TARGET_NOT_ENEMY)
		return		
	end
	human.db.enemyLen = human.db.enemyLen - 1
  for i=0, human.db.enemyLen - 1 do
    if delIndex >= i then
      human.db.enemy[i].uuid = human.db.enemy[i+1].uuid 
      human.db.enemy[i].revengeTimes = human.db.enemy[i+1].revengeTimes 
      human.db.enemy[i].killedTimes = human.db.enemy[i+1].killedTimes 
    end
  end 
	local msgRet = Msg.gc.GC_FRIEND_DEL
	msgRet.type = FriendDefine.DEL_ENEMY
	msgRet.srcUuid = human._id
	msgRet.targetUuid = targetUuid
	Msg.send(msgRet, human.fd)	
	Broadcast.sendBroadcast(human,Lang.DOWN,Lang.FRIEND_TARGET_DEL_ENEMY_OK)		
end

function getOnlineFriendFds(uuid,addTarget)
	local fds = {}
	local onlineUuid = Human.onlineUuid
	local target = onlineUuid[uuid]
	if target then
		for uuid in pairs(target.friend) do  
			local friend = onlineUuid[uuid]
			if friend and friend.fd then
				fds[#fds + 1] = friend.fd
			end
		end
	else
		local data = FriendDBLogic.getFriends(uuid)
		if data then
			for uuid in pairs(data) do 
				local friend = onlineUuid[uuid]
				if friend and friend.fd then
					fds[#fds + 1] = friend.fd
				end
			end
		end
	end
	if target and addTarget then
		if target.fd then
			fds[#fds + 1] = target.fd
		end
	end
	fds[0] = #fds
	return fds
end
-- 判断是否是好友
function isFriend(uuid1, uuid2)
	return FriendDBLogic.isFriend(uuid1,uuid2)
end

-- 判断好友列表是否已满
function isFriendListFull(uuid)
	return FriendDBLogic.getFriendCnt(uuid) >= FriendDefine.FRIEND_COUNT
end

-- 判断黑名单列表是否已满
function isBlackListFull(human)
	return human.db.blackLen >= FriendDefine.BLACK_COUNT
end

-- 判断最近联系单列表是否已满
function isRecentListFull(human)
	return getLen(human.db.recent) >= FriendDefine.RECENT_COUNT
end

-- 判断是否是黑名单
function isBlack(db, uuid)
  for i=0, db.blackLen - 1 do
    if RoleFFI.ffi_string(db.black[i].uuid)  == uuid then
       return true
    end
  end
  return false
end

-- 判断是否最近联系人
function isRecent(db,uuid)
	return db.recent[uuid] ~= nil
end

function getLen(table)
	return FriendDBLogic.getLen(table)
end

function addRecentLoigc(copyID, roomID)
	local humanTable = Copy.getCopyHumanList(copyID, roomID)
	for _,human in ipairs(humanTable) do 
		for _,target in ipairs(humanTable) do 
			local team = TeamLogic.getTeamByUuid(human._id)
			if team and human ~= target then
				local member = TeamLogic.getMember(team,target._id)
				if member then
					addRecent(human,target._id)	
				end
			end 
		end
	end
end

function onRoomFinishCB(copyID, roomID)
	-- 添加最近联系人
	addRecentLoigc(copyID, roomID)
	-- 添加亲密度
	addQinmiByCopy(copyID,roomID)
end

function CG_FRIEND_QINMI_CONF_QUERY(human)
	local msgRet = Msg.gc.GC_FRIEND_QINMI_CONF_QUERY
	msgRet.desc = QinmiArgConf.desc
	msgRet.items[0] = 0
	for _ ,conf in ipairs(FriendExcel.qinmiRange) do 
		msgRet.items[0] = msgRet.items[0] + 1
		local msgItem = msgRet.items[msgRet.items[0]]
		msgItem.id = conf.id
		msgItem.name = conf.name
		msgItem.down = conf.down
		msgItem.up = conf.up
		msgItem.attrs[0] = 0
		for key,value in pairs(conf.attrs) do 
			msgItem.attrs[0] = msgItem.attrs[0] + 1
			local attr = msgItem.attrs[msgItem.attrs[0]]
			attr.key = key
			attr.value = value
		end
	end
	Msg.send(msgRet,human.fd)
end

function setQinmi(human,target,qinmi)
	if not human and not target then
		assert()
	end
	local humanData = human.friend[target._id]
	local targetData = target.friend[human._id]
	if humanData._id ~= targetData._id then
		assert()
	end
	if not humanData.qinmi then
		humanData.qinmi = 0
	end
	humanData.qinmi = humanData.qinmi + qinmi
	targetData.qinmi = humanData.qinmi
	FriendDBLogic.saveFriend(humanData)
	
	-- 更新亲密度
	sendOnLineNotify(human,target.fd,humanData,FriendDefine.FRIEND)
	sendOnLineNotify(target,human.fd,targetData,FriendDefine.FRIEND)

	Broadcast.sendBroadcast(human,Lang.CHAT,string.format(Lang.FRINED_QINMI,HtmlUtil.fontNameKuo(target.db.name,target._id),humanData.qinmi))
	Broadcast.sendBroadcast(target,Lang.CHAT,string.format(Lang.FRINED_QINMI,HtmlUtil.fontNameKuo(human.db.name,human._id),humanData.qinmi))	
	
	local sameTeam = TeamLogic.inSameTeam(human._id,target._id)
	if sameTeam then
		local team = TeamLogic.getTeamByUuid(human._id)
		if team then
			checkQinmiBuff(team)
		end
	end
	
end

-- 鲜花亲密度
function addQinmiByFlower(human,target,cnt)
	if Config.IS_MIDDLE then
		return 0
	end 
	local flowerQinmi = QinmiArgConf.flowerQinmi
	local qinmi = flowerQinmi * cnt
	setQinmi(human,target,qinmi)	
	return qinmi
end

-- 副本亲密度
qinmiMap = qinmiMap or {}
function addQinmiByCopy(copyID, roomID)
	
	if Config.IS_MIDDLE then
		return
	end 
	
	-- clear
	for key in pairs(qinmiMap) do 
		qinmiMap[key] = nil
	end
	
	local humanTable = Copy.getCopyHumanList(copyID, roomID)
	for _,human in ipairs(humanTable) do 
		for _,target in ipairs(humanTable) do 
			if human ~= target then
				local friendData = human.friend[target._id]
				if friendData and not qinmiMap[friendData._id] then
					qinmiMap[friendData._id] = 1
					setQinmi(human,target,QinmiArgConf.copyQinmi)
				end
			end
		end
	end
		
end

-- 击杀BOSS亲密度
function addQinmiByBoss(human)
	
	if Config.IS_MIDDLE then
		return
	end 
	
	local team = TeamLogic.getTeamByUuid(human._id)
	if not team then
		return
	end
	
	-- clear
	for key in pairs(qinmiMap) do 
		qinmiMap[key] = nil
	end
	
	local onlineUuid = Human.onlineUuid
	for i = 1, TeamLogic.TEAM_MAX_MEMBER_COUNT do
		local member1 = team[i]
		if member1 then
			local target1 = onlineUuid[member1.uuid]
			if target1 then
				for j = 1, TeamLogic.TEAM_MAX_MEMBER_COUNT do
					local member2 = team[j]
					if member2 then
						local target2 = onlineUuid[member2.uuid]
						if target2 then
							local friendData = target1.friend[target2._id]
							if target1 ~= target2 and friendData and target1.scene_id == target2.scene_id and not qinmiMap[friendData._id] then
								qinmiMap[friendData._id] = 1
								setQinmi(target1,target2,QinmiArgConf.bossQinmi)
							end
						end
					end
				end
			end		
		end
	end
	
end

local function updateDaily(data)
	if data.update_daily_time and Util.isSameDay(data.update_daily_time) then
		return
	end
	data.update_daily_time = os.time()
	data.dailySitQinmi = nil
	FriendDBLogic.saveFriend(data)
end

-- 双休亲密度
function addQinmiByDoubleSit(human)
	
	if Config.IS_MIDDLE then
		return
	end 
	
	local target = Human.onlineUuid[human.sitDoubleUuid]
	if not target then
		return
	end
	
	local humanData = human.friend[target._id]
	local targetData = target.friend[human._id]
	if not humanData or not targetData then
		return	
	end
	
	if humanData._id ~= targetData._id then
		assert()
	end
	
	local now = os.time()
	if human.sitDoubleQinmiStartTime and now - human.sitDoubleQinmiStartTime < QinmiArgConf.sitTime then
		return
	end
	-- 更新
	human.sitDoubleQinmiStartTime = now
	target.sitDoubleQinmiStartTime = now
	
	updateDaily(humanData)
	updateDaily(targetData)
	local nowDailySitQinmi = humanData.dailySitQinmi
	if nowDailySitQinmi and nowDailySitQinmi >= QinmiArgConf.sitQinmiLimite then
		return
	end
	
	if not humanData.dailySitQinmi then
		humanData.dailySitQinmi = 0
	end
	
	humanData.dailySitQinmi = humanData.dailySitQinmi + QinmiArgConf.sitQinmi
	if humanData ~= targetData then
		
		if not targetData.dailySitQinmi then
			targetData.dailySitQinmi = 0
		end
		
		targetData.dailySitQinmi = targetData.dailySitQinmi + QinmiArgConf.sitQinmi
		
	end 
	setQinmi(human,target,QinmiArgConf.sitQinmi)
	
end

function getQinmiID(human)
	local team = TeamLogic.getTeamByUuid(human._id)
	if not team then
		return 0
	end
	
	local maxQinmi = -1
	for j = 1,TeamLogic.TEAM_MAX_MEMBER_COUNT do
		local member = team[j]
		if member then
			local target = Human.onlineUuid[member.uuid]	
			if target and target ~= human then
				local friendData = human.friend[target._id]
				if friendData and human.scene_id == target.scene_id then
					local tmpQinmi = friendData.qinmi or 0
					maxQinmi = math.max(maxQinmi,tmpQinmi)		
				end
			end	
		end
	end
	
	if maxQinmi == -1 then
		return 0
	end
	
	for _,conf in ipairs(QinmiRangeConf) do 
		if maxQinmi >= conf.down and (maxQinmi <= conf.up or conf.up == 0) then
			return conf.id
		end
	end
	
end

function calcByQinmiID(human,id)
	human.nowQinmiID = id
	Human.doCalc(human)
	
	local msgRet = Msg.gc.GC_QINMI_BUFF_QUERY
	msgRet.id = id
	Msg.send(msgRet,human.fd)
end

function checkQinmiBuff(team)
	for i = 1, TeamLogic.TEAM_MAX_MEMBER_COUNT do
		local member = team[i]
		if member then
			local target = Human.onlineUuid[member.uuid]
			if target then
				local nowID = getQinmiID(target)
				if target.nowQinmiID ~= nowID then
					calcByQinmiID(target,nowID)
				end
			end
		end
	end	
end

-- 进入场景
function onHumanEnterScene(human)
	if Config.IS_MIDDLE then
		return
	end 
	local team = TeamLogic.getTeamByUuid(human._id)
	if not team then
		return
	end
	checkQinmiBuff(team)
end

-- 队伍进入
function onAddMemberCB(team)
	if Config.IS_MIDDLE then
		return
	end 
	checkQinmiBuff(team)
end

-- 队伍出人
function onDelMemberCB(team,delUuid)
	if Config.IS_MIDDLE then
		return
	end 
	checkQinmiBuff(team)
	local human = Human.onlineUuid[delUuid]
	if not human or not human.fd then
		return
	end
	calcByQinmiID(human,0)
end

-- 队伍解散
function onDismissCB(team)
	if Config.IS_MIDDLE then
		return
	end 
	for i = 1, TeamLogic.TEAM_MAX_MEMBER_COUNT do
		local member = team[i]
		if member then
			local target = Human.onlineUuid[member.uuid]
			if target then
				calcByQinmiID(target,0)
			end
		end
	end 
end

-- 计算属性
function doCalc(human)
	
	if Config.IS_MIDDLE or not human.nowQinmiID or human.nowQinmiID == 0 then
		return
	end 
	
	local conf = QinmiRangeConf[human.nowQinmiID]
	if not conf then
		return
	end
	
	for key,value in pairs(conf.attrs) do 
		human.attr[key] = human.attr[key] + value
	end
	
end





